//
// Created by tongj on 2024/1/13.
//

#ifndef TBS_CPP_GUARD_CUH
#define TBS_CPP_GUARD_CUH

namespace tbs {
template<typename V, void (*E)(V *), void (*B)(V *)> Guard<V, E, B>::Guard(V *val) {
  ASSERT(val == nullptr, "need something to guard,can not be nullptr");
  this->value = val;
  if (B != nullptr) {
	B(this->value);
  }
}

template<typename V, void (*E)(V *), void (*B)(V *)>
Guard<V, E, B> &Guard<V, E, B>::operator=(Guard &&other) NO_EXCEPT {
  this->value = other.value;
  other.value = nullptr;
  return *this;
}

template<typename V, void (*E)(V *), void (*B)(V *)> Guard<V, E, B>::Guard(Guard &&other) NO_EXCEPT {
  this->value = other.value;
  other.value = nullptr;
}

template<typename V, void (*E)(V *), void (*B)(V *)> Guard<V, E, B>::~Guard() {
  if (E != nullptr && value != nullptr) {
	E(value);
  }
}

template<typename V, void (*E)(V *), void (*B)(V *)> V *Guard<V, E, B>::release() NO_EXCEPT {
  V *ptr = value;
  this->value = nullptr;
  return ptr;
}

template<typename V, void (*E)(V *), void (*B)(V *)> V &Guard<V, E, B>::get() NO_EXCEPT {
  return (*value);
}

template<typename V, void (*E)(V *), void (*B)(V *)> Guard<V, E, B> &Guard<V, E, B>::operator=(const V &val) {
  this->get() = val;
  return *this;
}
}

#endif //TBS_CPP_GUARD_CUH
